﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using OfficeOpenXml;
using UnityEditor;
using UnityEngine;

namespace Xls2Lua
{
    /// <summary>
    /// 负责最终文件的输出保存等操作类
    /// </summary>
    public class FileExporter
    {
        /// <summary>
        /// 开始读取数据行数
        /// </summary>
        public static int StartReadRow = 4;

        private static string hashFile = "";
        
        private static Dictionary<string,string> ExcelFileHashDic = new Dictionary<string, string>();
        private static Dictionary<string,string> NewFileHashDic = new Dictionary<string, string>();

        public static void ExportExcelToLua()
        {
            string excelPath = PlayerPrefs.GetString(Excel2ProtoTool.ExcelPathKey);
            string luaDataPath = PlayerPrefs.GetString(Excel2ProtoTool.ExportLuaDataPathKey);
            hashFile = $"{excelPath}/hashFile.txt";
            NewFileHashDic.Clear();
            ExcelFileHashDic.Clear();
            ReadExcelHash();
            ExportAllLuaFile(excelPath, luaDataPath);
            WriteExcelHash();
        }
        
        /// <summary>
        /// 初始化读取 表格 hash 值
        /// </summary>
        static void ReadExcelHash()
        {
            if (!File.Exists(hashFile))
            {
                File.Create(hashFile);
                return;
            }
            using (FileStream file = File.OpenRead(hashFile))
            {
                byte[] loadData = new byte[file.Length];
                file.Read(loadData, 0, (int) file.Length);
                var str = Encoding.UTF8.GetString(loadData);
                var strList = str.Split('\n');
                for (int i = 0; i < strList.Length; i++)
                {
                    var data = strList[i];
                    if (string.IsNullOrEmpty(data))
                    {
                        continue;
                    }
                    var dataList = data.Split(':');
                    ExcelFileHashDic.Add(dataList[0].Trim('\r'), dataList[1].Trim('\r'));
                }
            }
        }
        /// <summary>
        /// 打表完成 后 写入 子表 hash 值 到 文件内
        /// </summary>
        static void WriteExcelHash()
        {
            StringBuilder sb = new StringBuilder();
            using (FileStream file = File.OpenWrite(hashFile))
            {
                foreach (var value in NewFileHashDic)
                {
                    sb.AppendLine($"{value.Key}:{value.Value}");
                }
                byte[] data = Encoding.UTF8.GetBytes(sb.ToString());
                file.Write(data, 0, data.Length);
            }
        }

        /// <summary>
        /// 清空某个DIR下的内容
        /// </summary>
        /// <param name="dir"></param>
        public static void ClearDirectory(string dir)
        {
            if (!Directory.Exists(dir))
            {
                return;
            }
            Debug.Log("清空目录：" + dir);
            DirectoryInfo directoryInfo = new DirectoryInfo(dir);
            FileSystemInfo[] fileSystemInfos = directoryInfo.GetFileSystemInfos();

            foreach (var info in fileSystemInfos)
            {
                if (info is DirectoryInfo)
                {
                    DirectoryInfo subDir = new DirectoryInfo(info.FullName);
                    try
                    {
                        subDir.Delete(true);
                    }
                    catch (Exception e)
                    {
                        Debug.Log("警告：目录删除失败 " + e.Message);
                    }
                }
                else
                {
                    try
                    {
                        File.Delete(info.FullName);
                    }
                    catch (Exception e)
                    {
                        Debug.Log("警告：文件删除失败 " + e.Message);
                    }
                }
            }
        }

        /// <summary>
        /// 导出所有的Excel配置到对应的lua文件中
        /// </summary>
        /// <param name="inDir"></param>
        /// <param name="outDir"></param>
        public static void ExportAllLuaFile(string inDir, string outDir)
        {
            EditorUtility.DisplayProgressBar("Excel 打表进度", "Excel 转 Lua 数据 ...", 0);
            //ClearDirectory(outDir);
            List<string> allXlsList = Directory.GetFiles(inDir, "*.xlsx", SearchOption.AllDirectories).ToList();
            Debug.Log("开始转表...");
            float i = 0;
            int count = allXlsList.Count;
            EditorUtility.DisplayProgressBar("Excel 打表进度", "Excel 转 Lua 数据 ...", 0.15f);
            foreach (var curXlsName in allXlsList)
            {
                i += 1f;
                ExportSingleLuaFile(curXlsName, outDir, i, count);
                EditorUtility.DisplayProgressBar("Excel 打表进度", "Excel 转 Lua 数据 ...", 0.15f + i / count * 0.85f);
            }
            EditorUtility.DisplayProgressBar("Excel 打表进度", "Excel 转 Lua Success ...", 1);
            EditorUtility.ClearProgressBar();
        }

        public static void ExportSingleLuaFile(string xlsName, string outDir,float progress,float count)
        {
            EditorUtility.DisplayProgressBar("Excel 打表进度", "Excel 转 Lua 数据 ...", 0.15f + progress * 0.2f / count * 0.85f);
            if (string.IsNullOrEmpty(xlsName))
            {
                return;
            }
            if (".xlsx" != Path.GetExtension(xlsName).ToLower())
            {
                return;
            }

            Console.WriteLine(Path.GetFileName(xlsName));

            //打开文件流
            FileStream fs = null;
            try
            {
                fs = File.OpenRead(xlsName);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                throw;
            }
            EditorUtility.DisplayProgressBar("Excel 打表进度", "Excel 转 Lua 数据 ...", 0.15f + progress * 0.3f / count * 0.85f);
            //读取xls文件
            ExcelPackage excelPackage = new ExcelPackage(fs);
            ExcelWorkbook excelWorkbook = excelPackage.Workbook;
            ExcelWorksheets excelWorksheets = excelWorkbook.Worksheets;
            fs.Close();
            EditorUtility.DisplayProgressBar("Excel 打表进度", "Excel 转 Lua 数据 ...", 0.15f + progress * 0.4f / count * 0.85f);
            //循环处理sheet
            float i = 0;
            foreach (var sheet in excelWorksheets)
            {
                i += 1f;
                var newProgress = 0.15f + progress / count * 0.85f * (0.4f + 0.6f * (i / excelWorksheets.Count));
                EditorUtility.DisplayProgressBar("Excel 打表进度", "Excel 转 Lua 数据 ...", newProgress);
                string sheetName = XlsTransfer.GetSheetName(sheet);
                if (string.IsNullOrEmpty(sheetName)) continue;
                sheetName = sheetName.Substring(1, sheetName.Length - 1);

                var hashCode = sheet.GetHashCode(sheet).ToString();
                NewFileHashDic.Add(sheetName, hashCode);
                if (ExcelFileHashDic.TryGetValue(sheetName,out var code))
                {
                    if (hashCode.Equals(code))
                    {
                        continue;
                    }
                }
                Debug.Log("Sheet:" + sheetName);
                string outPath = Path.Combine(outDir, sheetName + ".lua");
                string content = XlsTransfer.GenLuaFile(sheet);
                if (!string.IsNullOrEmpty(content))
                {
                    File.WriteAllText(outPath, content);
                }
            }
        }
    }
}